package io.github.echarts.model.theme.provider;

import io.github.echarts.model.context.ConfigurationContext;
import io.github.echarts.model.theme.AbstractDefaultValueProvider;
import io.github.echarts.model.theme.Theme;
import io.github.echarts.option.series.BarSeries;
import io.github.echarts.option.series.LineSeries;
import io.github.echarts.option.series.PieSeries;
import io.github.echarts.option.series.ScatterSeries;
import io.github.echarts.option.series.SeriesOption;
import io.github.echarts.option.style.AreaStyle;
import io.github.echarts.option.style.ItemStyle;
import io.github.echarts.option.style.LabelStyle;
import io.github.echarts.option.style.LineStyle;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 系列默认值提供者
 * <p>
 * 为系列组件提供默认配置，包括各种系列类型（折线图、柱状图、饼图等）的样式和行为。
 * 根据系列类型应用特定默认设置。
 * </p>
 */
public class SeriesDefaultValueProvider extends AbstractDefaultValueProvider<SeriesOption> {
    
    /**
     * 系列类型特定配置处理器映射
     */
    private final Map<String, Consumer<SeriesOption>> seriesTypeHandlers = new HashMap<>();
    
    /**
     * 构造函数
     */
    public SeriesDefaultValueProvider() {
        super(SeriesOption.class);
        initSeriesTypeHandlers();
    }
    
    /**
     * 初始化系列类型处理器
     */
    private void initSeriesTypeHandlers() {
        // 注册各种系列类型的处理器
        seriesTypeHandlers.put("line", this::applyLineDefaults);
        seriesTypeHandlers.put("bar", this::applyBarDefaults);
        seriesTypeHandlers.put("pie", this::applyPieDefaults);
        seriesTypeHandlers.put("scatter", this::applyScatterDefaults);
        // 可以添加更多系列类型的处理器
    }
    
    @Override
    protected void initDefaultValues() {
        // 基本属性
        registerDefaultValue("animation", true);
        registerDefaultValue("silent", false);
        registerDefaultValue("legendHoverLink", true);
        registerDefaultValue("zlevel", 0);
        registerDefaultValue("z", 2);
    }
    
    @Override
    public void applyDefaults(SeriesOption series, ConfigurationContext context) {
        super.applyDefaults(series, context);
        
        // 确保基本项样式
        if (series.getItemStyle() == null) {
            series.setItemStyle(new ItemStyle());
        }
        
        // 根据系列类型应用特定默认值
        String type = series.getType();
        if (type != null && seriesTypeHandlers.containsKey(type)) {
            seriesTypeHandlers.get(type).accept(series);
        }
        
        // 应用图表尺寸相关的默认值
        applyChartSizeBasedDefaults(series, context);
    }
    
    /**
     * 根据图表尺寸应用默认值
     * 
     * @param series 系列选项
     * @param context 配置上下文
     */
    private void applyChartSizeBasedDefaults(SeriesOption series, ConfigurationContext context) {
        if (context == null) {
            return;
        }
        
        // 获取图表宽度和高度
        Integer width = (Integer) context.get("width");
        Integer height = (Integer) context.get("height");
        
        // 如果是小尺寸图表
        boolean isSmallChart = (width != null && width < 300) || (height != null && height < 200);
        
        if (isSmallChart) {
            // 小图表通常需要简化显示
            simplifyForSmallChart(series);
        }
    }
    
    /**
     * 为小尺寸图表简化系列配置
     * 
     * @param series 系列选项
     */
    private void simplifyForSmallChart(SeriesOption series) {
        // 隐藏标签
        LabelStyle label = series.getLabel();
        if (label != null) {
            label.setShow(false);
        }
        
        // 减小符号大小
        if (series instanceof LineSeries) {
            LineSeries lineSeries = (LineSeries) series;
            if (lineSeries.getSymbolSize() == null) {
                lineSeries.setSymbolSize(4);
            }
        } else if (series instanceof ScatterSeries) {
            ScatterSeries scatterSeries = (ScatterSeries) series;
            if (scatterSeries.getSymbolSize() == null) {
                scatterSeries.setSymbolSize(4);
            }
        } else if (series instanceof BarSeries) {
            BarSeries barSeries = (BarSeries) series;
            // 不设置barWidth，因为它只接受Integer参数
        }
    }
    
    /**
     * 应用折线图默认值
     * 
     * @param series 系列选项
     */
    private void applyLineDefaults(SeriesOption series) {
        if (!(series instanceof LineSeries)) {
            return;
        }
        
        LineSeries lineSeries = (LineSeries) series;
        
        // 默认显示符号
        if (lineSeries.getShowSymbol() == null) {
            lineSeries.setShowSymbol(true);
        }
        
        // 默认符号大小
        if (lineSeries.getSymbolSize() == null) {
            lineSeries.setSymbolSize(6);
        }
        
        // 默认线条样式
        if (lineSeries.getLineStyle() == null) {
            LineStyle lineStyle = new LineStyle();
            lineStyle.setWidth(2);
            lineStyle.setType("solid");
            lineSeries.setLineStyle(lineStyle);
        }
        
        // 默认不平滑
        if (lineSeries.getSmooth() == null) {
            lineSeries.setSmooth(false);
        }
        
        // 默认不设置面积样式
        if (lineSeries.getAreaStyle() == null) {
            // 面积样式不设置，表示不显示面积
        }
        
        // 默认标签配置
        if (lineSeries.getLabel() == null) {
            LabelStyle label = new LabelStyle();
            label.setShow(false);  // 默认不显示标签
            lineSeries.setLabel(label);
        }
    }
    
    /**
     * 应用柱状图默认值
     * 
     * @param series 系列选项
     */
    private void applyBarDefaults(SeriesOption series) {
        if (!(series instanceof BarSeries)) {
            return;
        }
        
        BarSeries barSeries = (BarSeries) series;
        
        // 由于BarSeries只接受Integer参数，所以这里不设置相关属性
        // 如果需要可以将百分比转为像素值
        
        // 默认不显示背景
        if (barSeries.getShowBackground() == null) {
            barSeries.setShowBackground(false);
        }
        
        // 默认标签配置
        if (barSeries.getLabel() == null) {
            LabelStyle label = new LabelStyle();
            label.setShow(false);  // 默认不显示标签
            barSeries.setLabel(label);
        }
    }
    
    /**
     * 应用饼图默认值
     * 
     * @param series 系列选项
     */
    private void applyPieDefaults(SeriesOption series) {
        if (!(series instanceof PieSeries)) {
            return;
        }
        
        PieSeries pieSeries = (PieSeries) series;
        
        // 默认半径
        if (pieSeries.getRadius() == null) {
            pieSeries.setRadius("75%");
        }
        
        // 默认圆心位置
        if (pieSeries.getCenter() == null) {
            // 分别设置x和y坐标
            pieSeries.setCenter("50%", "50%");
        }
        
        // 默认起始角度
        if (pieSeries.getStartAngle() == null) {
            pieSeries.setStartAngle(90.0); // 使用Double类型
        }
        
        // 默认最小角度
        if (pieSeries.getMinAngle() == null) {
            pieSeries.setMinAngle(0.0); // 使用Double类型
        }
        
        // 默认标签配置
        if (pieSeries.getLabel() == null) {
            LabelStyle label = new LabelStyle();
            label.setShow(true);
            label.setPosition("outer");
            pieSeries.setLabel(label);
        }
        
        // 默认不渲染成玫瑰图
        // 设置RoseType为字符串类型
        if (pieSeries.getRoseType() == null) {
            pieSeries.setRoseType("false");
        }
    }
    
    /**
     * 应用散点图默认值
     * 
     * @param series 系列选项
     */
    private void applyScatterDefaults(SeriesOption series) {
        if (!(series instanceof ScatterSeries)) {
            return;
        }
        
        ScatterSeries scatterSeries = (ScatterSeries) series;
        
        // 默认符号大小
        if (scatterSeries.getSymbolSize() == null) {
            scatterSeries.setSymbolSize(10); // 使用Integer类型
        }
        
        // 默认符号类型
        if (scatterSeries.getSymbol() == null) {
            scatterSeries.setSymbol("circle");
        }
        
        // 默认标签配置
        if (scatterSeries.getLabel() == null) {
            LabelStyle label = new LabelStyle();
            label.setShow(false);  // 默认不显示标签
            scatterSeries.setLabel(label);
        }
    }
    
    @Override
    protected void applyDataDrivenDefaults(SeriesOption series, ConfigurationContext context) {
        // 根据数据特征调整系列配置
        if (context == null) {
            return;
        }
        
        // 获取数据特征
        Integer dataCount = getDataCount(context);
        Boolean hasNegativeValues = getBooleanFeature(context, "hasNegativeValues");
        Boolean isLargeDataset = getBooleanFeature(context, "isLargeDataset");
        Boolean hasManyZeroValues = getBooleanFeature(context, "hasManyZeroValues");
        
        // 根据数据点数量调整
        if (dataCount != null && dataCount > 50) {
            // 数据点较多时，折线图可能不需要显示所有点的符号
            if (series instanceof LineSeries) {
                LineSeries lineSeries = (LineSeries) series;
                if (lineSeries.getShowSymbol() == null) {
                    lineSeries.setShowSymbol(false);
                }
            }
        }
        
        // 处理大数据集
        if (Boolean.TRUE.equals(isLargeDataset)) {
            applySamplingForLargeDataset(series);
        }
        
        // 处理有许多零值的情况
        if (Boolean.TRUE.equals(hasManyZeroValues)) {
            // 可能需要调整系列的显示策略
        }
    }
    
    /**
     * 为大数据集应用采样策略
     * 
     * @param series 系列选项
     */
    private void applySamplingForLargeDataset(SeriesOption series) {
        // 对于折线图，可能需要应用抽样算法
        if (series instanceof LineSeries) {
            LineSeries lineSeries = (LineSeries) series;
            
            // LineSeries没有sampling相关方法，注释相关代码
            
            // 大数据量时不显示所有符号
            lineSeries.setShowSymbol(false);
            
            // 大数据集的折线图可能会使用渐变的面积填充
            if (lineSeries.getAreaStyle() == null) {
                AreaStyle areaStyle = new AreaStyle();
                areaStyle.setOpacity(0.2);  // 轻微的面积填充
                lineSeries.setAreaStyle(areaStyle);
            }
        }
    }
    
    @Override
    public void ensureCompleteness(SeriesOption series, ConfigurationContext context) {
        // 确保项样式对象的完整性
        if (series.getItemStyle() == null) {
            series.setItemStyle(new ItemStyle());
        }
        
        // 确保系列有名称
        if (series.getName() == null) {
            series.setName("Series " + getNextSeriesIndex(context));
        }
        
        // 确保系列有类型
        if (series.getType() == null) {
            // 默认为折线图
            series.setSeriesType("line"); // 使用public方法setSeriesType
        }
        
        // 确保标签样式的完整性
        if (series.getLabel() == null) {
            series.setLabel(new LabelStyle());
        }
    }
    
    @Override
    public void applyTheme(SeriesOption series, Theme theme) {
        if (series == null || theme == null) {
            return;
        }
        
        // 获取系列索引
        int seriesIndex = getSeriesIndex(series);
        
        // 应用主题中的系列颜色
        String seriesColor = theme.getSeriesColor(seriesIndex);
        
        // 应用颜色到项样式
        if (series.getItemStyle() != null) {
            ItemStyle itemStyle = series.getItemStyle();
            if (itemStyle.getColor() == null) {
                itemStyle.setColor(seriesColor);
            }
        } else {
            ItemStyle itemStyle = new ItemStyle();
            itemStyle.setColor(seriesColor);
            series.setItemStyle(itemStyle);
        }
        
        // 应用线条样式
        if (series instanceof LineSeries) {
            LineSeries lineSeries = (LineSeries) series;
            if (lineSeries.getLineStyle() != null) {
                LineStyle lineStyle = lineSeries.getLineStyle();
                if (lineStyle.getColor() == null) {
                    lineStyle.setColor(seriesColor);
                }
            } else {
                LineStyle lineStyle = new LineStyle();
                lineStyle.setColor(seriesColor);
                lineStyle.setWidth(2);
                lineSeries.setLineStyle(lineStyle);
            }
        }
    }
    
    /**
     * 获取系列索引
     * 
     * @param series 系列选项
     * @return 系列索引
     */
    private int getSeriesIndex(SeriesOption series) {
        // 尝试从系列的索引属性获取
        Object indexObj = getFieldValueSafely(series, "index");
        if (indexObj instanceof Number) {
            return ((Number) indexObj).intValue();
        }
        
        // 返回默认索引0
        return 0;
    }
    
    /**
     * 安全地获取对象的字段值
     * 
     * @param object 对象
     * @param fieldName 字段名
     * @return 字段值，如果获取失败则返回null
     */
    private Object getFieldValueSafely(Object object, String fieldName) {
        try {
            java.lang.reflect.Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(object);
        } catch (Exception e) {
            // 忽略异常
            return null;
        }
    }
    
    /**
     * 获取数据点数量
     * 
     * @param context 配置上下文
     * @return 数据点数量
     */
    private Integer getDataCount(ConfigurationContext context) {
        Object dataCountObj = context.get("dataCount");
        if (dataCountObj instanceof Number) {
            return ((Number) dataCountObj).intValue();
        }
        return null;
    }
    
    /**
     * 获取布尔类型特征
     * 
     * @param context 配置上下文
     * @param key 特征键
     * @return 特征值
     */
    private Boolean getBooleanFeature(ConfigurationContext context, String key) {
        Object featureObj = context.get(key);
        if (featureObj instanceof Boolean) {
            return (Boolean) featureObj;
        }
        return null;
    }
    
    /**
     * 获取下一个系列索引
     * 
     * @param context 配置上下文
     * @return 系列索引
     */
    private int getNextSeriesIndex(ConfigurationContext context) {
        if (context == null) {
            return 0;
        }
        
        Object currentSeriesCountObj = context.get("currentSeriesCount");
        int currentSeriesCount = 0;
        
        if (currentSeriesCountObj instanceof Number) {
            currentSeriesCount = ((Number) currentSeriesCountObj).intValue();
        }
        
        // 增加系列计数并更新上下文
        context.put("currentSeriesCount", currentSeriesCount + 1);
        
        return currentSeriesCount;
    }
} 